﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Input;
using Microsoft.Win32;
using System.Windows;
using System.Xml;
using SHomeWorkshop.LunarConcept.Controls;
using SHomeWorkshop.LunarConcept.ModifingManager;
using System.Windows.Controls;

namespace SHomeWorkshop.LunarConcept.Commands
{
    /// <summary>
    /// 创建时间：2012年1月4日
    /// 创建者：  杨震宇
    /// 
    /// 主要用途：设置页面的尺寸（根据PaperInfo的支持，可设置A1-A10,B1-B10）。
    /// ★★说明：关于自定义命令的实现，可参考“NewDocument”类的备注。
    /// </summary>
    public static class SetPaperSizeCommand
    {
        #region 构造方法=====================================================================================================

        /// <summary>
        /// ★②，修改静态构造方法名。
        /// </summary>
        static SetPaperSizeCommand()//类型构造器
        {
            //★③，修改两个字符串参数名。★④以及第三个参数的类型名。
            routedUICmd = new RoutedUICommand(
                "SetPaperSizeCommand",
                "SetPaperSizeCommand",
                typeof(SetPaperSizeCommand),//创建RoutedUICommand对象
                null);

            //如果需要挂接快捷键，请参考下面这段代码：
            //routedUICmd = new RoutedUICommand(
            //    "SetPaperSizeCommand",
            //    "SetPaperSizeCommand",
            //    typeof(SetPaperSizeCommand),//创建RoutedUICommand对象
            //    new InputGestureCollection() 
            //    { 
            //        //★⑤，修改此处三个参数，以便挂接快捷键。
            //        new KeyGesture(Key.S,ModifierKeys.Control,"Ctrl+S")
            //    });

            cmdBinding.Command = routedUICmd;
            cmdBinding.CanExecute += new CanExecuteRoutedEventHandler(cmdBinding_CanExecute);
            cmdBinding.Executed += new ExecutedRoutedEventHandler(cmdBinding_Executed);
        }

        #endregion

        #region 字段与属性===================================================================================================

        private static CommandBinding cmdBinding = new CommandBinding();
        /// <summary>
        /// 用在主窗口CommandBindings集合中的命令绑定。
        /// 
        /// 它的Command是RoutedUICommand。
        /// ——因此，RoutedUICommand是否可以运行将由CmdBinding的CanExecute事件决定。
        /// ——而且，RoutedUICommand的执行也是通过CmdBinding的Execute事件来进行的。
        /// </summary>
        public static CommandBinding CmdBinding
        {
            get { return cmdBinding; }
        }

        private static RoutedUICommand routedUICmd;
        /// <summary>
        /// [只读静态属性]表示在WPF系统中注册的一个RoutedUICommand。
        /// ——必须和CommandBinding配合才能使用。
        ///     CommandBinding要添加到主窗口的CommandBindings集合中；
        ///     RoutedUICommand则要向WPF系统注册。
        ///     
        /// ★说明：使用静态属性是因为这样在Xaml代码中比较便于绑定。
        /// </summary>
        public static RoutedUICommand RoutedUICmd
        {
            get { return routedUICmd; }
        }

        #endregion

        #region 方法=========================================================================================================

        static void cmdBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            //★⑧，修改此方法的实现。

            //考虑到性能问题，全部取消此判断。反正执行时会判断。
            //if (Globals.MainWindow == null)
            //{
            //    e.CanExecute = false; return;
            //}

            //EditorManager manager = Globals.MainWindow.EditorManager;

            //if (manager == null)
            //{
            //    e.CanExecute = false; return;
            //}

            //if (manager.GetSelectedPageEditorCount() <= 0)
            //{
            //    e.CanExecute = false; return;
            //}

            e.CanExecute = true; return;
        }

        static void cmdBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            //★⑦，修改此方法的实现。

            LunarMessage.Warning(Execute(e.Parameter as string));
        }

        /// <summary>
        /// [公开静态方法]即使此命令处于禁用状态，也可以通过代码调用此方法来执行特定任务！！！
        /// 
        /// 当被绑定的命令被调用（触发）时，会引发cmdBinding_Executed事件。
        /// 在cmdBinding_Executed事件处理器方法中已添加了调用Execute()方法的代码。
        /// 
        /// ——因此，触发命令，就相当于调用此方法！！！
        /// </summary>
        public static string Execute(string newPaperTypeName = "A4")
        {
            if (PaperInfo.IsValidatePaperName(newPaperTypeName) == false)
                return "　　指定的纸型名称不合法。纸型名称只支持[A0-A10]、[B0-B10]、Slide、[1K|2K|4K|8K|16K|32K]或[xxhdpi|xhdpi|hdpi|mhdpi|lhdpi]或[Auto(a)|User(u)|Custom(c)]。\r\n\r\n" +
                    "　　其中：\r\n" +
                    "　　　Slide可以是：Slide640*480/Slide800*600/Slide1024*768/Slide1760*810这几种之一；\r\n" +
                    "　　　Auto是自动根据当前可视区尺寸（这是为了演示方便），可以只写首字母；\r\n" +
                    "　　　Custom|user等价，用以输入自定义尺寸，也可以只输入首字母。";

            if (Globals.MainWindow == null) return "　　未找到Globals.MainWindow。";

            EditorManager manager = Globals.MainWindow.EditorManager;
            if (manager == null) return "　　未找到页面管理器。";

            List<PageEditor> selPageEditors = manager.GetSelectedPageEditorsList();
            if (selPageEditors.Count <= 0) return "　　未选定页面。";

            var customSizeList = new List<string>();
            customSizeList.Add("c");
            customSizeList.Add("custom");
            customSizeList.Add("u");
            customSizeList.Add("user");

            var autoSizeList = new List<string>();
            autoSizeList.Add("a");
            autoSizeList.Add("auto");

            bool autoSize = false;

            if (customSizeList.Contains(newPaperTypeName.ToLower()))
            {
                var spe = selPageEditors[0];
                string defVal = "";
                switch (spe.PaperDirection)
                {
                    case Orientation.Horizontal:
                        {
                            defVal = spe.PaperSize.LongSideWPFUnit + "*" + spe.PaperSize.ShortSideWPFUnit;
                            break;
                        }
                    default:
                        {
                            defVal = spe.PaperSize.ShortSideWPFUnit + "*" + spe.PaperSize.LongSideWPFUnit;
                            break;
                        }
                }

                string ipt = InputBox.Show(Globals.AppName, "请输入新的[宽*高]值：", defVal, false);
                if (string.IsNullOrEmpty(ipt)) return "";

                var a = ipt.Split(new char[] { ':', '：', '*', '＊', '╳', '＊', ' ', '/', '×' }, StringSplitOptions.RemoveEmptyEntries);
                if (a.Length != 2) return "输入值非法！";

                var trimChars = new char[] { ' ', '　', '\t' };
                if (double.TryParse(a[0].Trim(trimChars), out double w) == false ||
                    double.TryParse(a[1].Trim(trimChars), out double h) == false) return "输入值非法！";

                if (w < 98.3 || h < 98.3) return "宽高不能小于 100 ！";

                newPaperTypeName = "custom" + w + "*" + h;
            }
            else if (autoSizeList.Contains(newPaperTypeName.ToLower()))
            {
                //var oldWindowStyle = Globals.MainWindow.WindowStyle;
                //var oldWindowState = Globals.MainWindow.WindowState;

                //Globals.MainWindow.WindowStyle = WindowStyle.None;
                //Globals.MainWindow.WindowState = WindowState.Maximized;
                //Globals.MainWindow.Ribbon.Visibility = Visibility.Collapsed;
                //Globals.MainWindow.TCBottomTools.Visibility = Visibility.Collapsed;
                //Globals.MainWindow.DPStatus.Visibility = Visibility.Collapsed;
                //Globals.MainWindow.rdRibbon.Height = new GridLength(0, GridUnitType.Pixel);
                //Globals.MainWindow.rdStatus.Height = new GridLength(0, GridUnitType.Pixel);

                if (Globals.MainWindow.TCRightTools.ActualWidth > 0)
                {
                    Globals.MainWindow.TCRightTools.Visibility = Visibility.Collapsed;
                }

                if (Globals.MainWindow.TCLeftTools.ActualWidth > 0)
                {
                    Globals.MainWindow.TCLeftTools.Visibility = Visibility.Collapsed;
                }

                if (Globals.MainWindow.Ribbon.IsMinimized == false)
                {
                    Globals.MainWindow.RTBtnMinimizeRibbon.IsChecked = true;

                    Globals.MainWindow.DPStatus.Visibility = Visibility.Collapsed;
                    Globals.MainWindow.rdStatus.Height = new GridLength(0, GridUnitType.Pixel);

                    Globals.MainWindow.InvalidateArrange();
                    Globals.MainWindow.UpdateLayout();
                }

                autoSize = true;

                // 这个只支持横向
                string defVal = (Globals.MainWindow.MainScrollViewer.ViewportWidth - 60) * 0.9 + "*" + (Globals.MainWindow.MainScrollViewer.ViewportHeight - 25) * 0.9;

                var a = defVal.Split(new char[] { ':', '：', '*', '＊', '╳', '＊', ' ', '/', '×' }, StringSplitOptions.RemoveEmptyEntries);
                if (a.Length != 2) return "输入值非法！";

                var trimChars = new char[] { ' ', '　', '\t' };
                if (double.TryParse(a[0].Trim(trimChars), out double w) == false ||
                    double.TryParse(a[1].Trim(trimChars), out double h) == false) return "输入值非法！";

                if (w < 98.3 || h < 98.3) return "宽高不能小于 100 ！";

                newPaperTypeName = "custom" + w + "*" + h;

                //Globals.MainWindow.WindowStyle = oldWindowStyle;
                //Globals.MainWindow.WindowState = oldWindowState;

                //Globals.MainWindow.TCRightTools.Visibility = Visibility.Visible;
                //Globals.MainWindow.TCLeftTools.Visibility = Visibility.Visible;
                //Globals.MainWindow.TCBottomTools.Visibility = Visibility.Visible;
                //Globals.MainWindow.Ribbon.Visibility = Visibility.Visible;
                //Globals.MainWindow.DPStatus.Visibility = Visibility.Visible;

                //Globals.MainWindow.rdRibbon.Height = new GridLength(1, GridUnitType.Auto);
                //Globals.MainWindow.rdStatus.Height = new GridLength(28, GridUnitType.Pixel);

                Globals.MainWindow.DPStatus.Visibility = Visibility.Visible;
                Globals.MainWindow.rdStatus.Height = new GridLength(28, GridUnitType.Pixel);
            }
            else if (newPaperTypeName.ToLower().StartsWith("custom"))
            {
                var t = newPaperTypeName.Substring(6);
                var a = t.Split(new char[] { ':', '：', '*', '＊', '╳', '＊', ' ', '/', '×' }, StringSplitOptions.RemoveEmptyEntries);
                if (a.Length != 2) return "提供的自定义尺寸不合法";

                var trimChars = new char[] { ' ', '　', '\t' };
                if (double.TryParse(a[0].Trim(trimChars), out double w) == false ||
                    double.TryParse(a[1].Trim(trimChars), out double h) == false) return "提供的自定义尺寸不合法";

                newPaperTypeName = "custom" + w + "*" + h;
            }

            ModifingInfo info = new ModifingInfo();
            manager.GetSelectedPageEditorStatus(info);
            manager.GetSelectedWidgetStatus_Old(info);
            manager.GetSelectedWidgetStatus_New(info);

            info.ModifingDescription = "设置纸型";

            ModifingItem<Action, ModifingInfo> mi = new ModifingItem<Action, ModifingInfo>(info);

            foreach (PageEditor pe in selPageEditors)
            {
                if (pe.PaperSize.PaperTypeName != newPaperTypeName)
                {
                    Action actPaperSizeSetting = new Action(ActionType.PaperSizeSetting, pe.Id, pe.PaperSize.PaperTypeName,
                        newPaperTypeName);
                    pe.PaperSizeText = newPaperTypeName;
                    mi.AddAction(actPaperSizeSetting);
                }

                if ((newPaperTypeName.StartsWith("Slide", StringComparison.InvariantCultureIgnoreCase) || autoSize) && pe.PaperDirection != Orientation.Horizontal)
                {
                    Action actPaperDirection = new Action(ActionType.PaperDirectionSetting, pe.Id, pe.PaperDirection.ToString(),
                        Orientation.Horizontal.ToString());
                    pe.PaperDirection = Orientation.Horizontal;
                    mi.AddAction(actPaperDirection);
                }
            }

            manager.RegisterModifingItem(mi);

            return string.Empty;
        }

        #endregion
    }
}
